<template>
  <div class="file-upload-wrapper">
    <!-- 上传区域 -->
    <div
      class="upload-area"
      :class="{
        'upload-area--disabled': disabled,
        'upload-area--dragover': isDragOver,
        'upload-area--has-files': currentFileList.length > 0
      }"
      @dragover.prevent="handleDragOver"
      @dragleave.prevent="handleDragLeave"
      @drop.prevent="handleDrop"
    >
      <a-upload
        :file-list="[]"
        :before-upload="handleBeforeUpload"
        :accept="accept"
        :multiple="multiple"
        :max-count="maxCount"
        :show-upload-list="false"
        class="upload-trigger"
      >
        <div class="upload-content">
          <div class="upload-icon">
            <CloudUploadOutlined v-if="!uploading" />
            <LoadingOutlined v-else class="upload-loading" />
          </div>
          <div class="upload-text">
            <div class="upload-title">
              {{ uploading ? '上传中...' : buttonText }}
            </div>
            <div class="upload-hint">
              支持拖拽文件到此区域上传
            </div>
            <div v-if="accept || allowedTypes.length > 0" class="upload-types">
              支持格式: {{ getAcceptedTypesText() }}
            </div>
          </div>
        </div>
      </a-upload>
    </div>

    <!-- 文件列表 -->
    <div v-if="currentFileList.length > 0" class="file-list">
      <div class="file-list-header">
        <span class="file-count">已选择 {{ currentFileList.length }} 个文件</span>
      </div>
      <div class="file-items">
        <div
          v-for="file in currentFileList"
          :key="file.uid"
          class="file-item"
        >
          <div class="file-info">
            <div class="file-icon">
              <FileTextOutlined />
            </div>
            <div class="file-details">
              <div class="file-name">{{ file.name }}</div>
              <div class="file-status">
                <CheckCircleOutlined class="status-success" />
                上传成功
              </div>
            </div>
          </div>
          <div class="file-actions">
            <a-button
              type="text"
              size="small"
              danger
              @click="handleRemoveFile(file)"
              class="remove-btn"
            >
              <DeleteOutlined />
            </a-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import { message } from 'ant-design-vue'
import {
  CloudUploadOutlined,
  LoadingOutlined,
  FileTextOutlined,
  CheckCircleOutlined,
  DeleteOutlined
} from '@ant-design/icons-vue'
import type { UploadProps } from 'ant-design-vue'

interface FileUploadProps {
  modelValue?: string | string[] // 当前文件路径（单个或多个）
  accept?: string // 接受的文件类型
  multiple?: boolean // 是否支持多选
  maxCount?: number // 最大文件数量
  buttonText?: string // 按钮文字
  disabled?: boolean // 是否禁用
  uploadUrl?: string // 上传接口地址
  maxSize?: number // 最大文件大小（MB）
  allowedTypes?: string[] // 允许的文件类型数组
}

interface FileUploadEmits {
  (e: 'update:modelValue', value: string | string[]): void
  (e: 'change', value: string | string[]): void
  (e: 'success', response: any, file: File): void
  (e: 'error', error: any, file: File): void
}

const props = withDefaults(defineProps<FileUploadProps>(), {
  accept: '',
  multiple: false,
  maxCount: 1,
  buttonText: '选择文件',
  disabled: false,
  uploadUrl: '/api/upload',
  maxSize: 10,
  allowedTypes: () => []
})

const emit = defineEmits<FileUploadEmits>()

// 当前文件列表
const currentFileList = ref<any[]>([])

// 拖拽和上传状态
const isDragOver = ref(false)
const uploading = ref(false)

// 根据modelValue生成文件列表
const generateFileList = (value: string | string[] | undefined) => {
  if (!value) return []

  const paths = Array.isArray(value) ? value : [value]
  return paths
    .filter(path => path && path.trim())
    .map((path, index) => ({
      uid: `${index}`,
      name: path.split('/').pop() || '未知文件',
      status: 'done',
      url: path,
      path: path
    }))
}

// 监听modelValue变化
watch(
  () => props.modelValue,
  (newValue) => {
    currentFileList.value = generateFileList(newValue)
  },
  { immediate: true }
)

// 文件大小验证
const validateFileSize = (file: File): boolean => {
  const sizeMB = file.size / 1024 / 1024
  if (sizeMB > props.maxSize) {
    message.error(`文件大小不能超过 ${props.maxSize}MB`)
    return false
  }
  return true
}

// 文件类型验证
const validateFileType = (file: File): boolean => {
  if (props.allowedTypes.length > 0) {
    const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase()
    if (!props.allowedTypes.includes(fileExtension)) {
      message.error(`只允许上传以下类型的文件: ${props.allowedTypes.join(', ')}`)
      return false
    }
  }
  return true
}

// 获取支持的文件类型文本
const getAcceptedTypesText = () => {
  if (props.allowedTypes.length > 0) {
    return props.allowedTypes.join(', ')
  }
  if (props.accept) {
    return props.accept.replace(/\./g, '').toUpperCase()
  }
  return '所有格式'
}

// 拖拽事件处理
const handleDragOver = (e: DragEvent) => {
  e.preventDefault()
  isDragOver.value = true
}

const handleDragLeave = (e: DragEvent) => {
  e.preventDefault()
  isDragOver.value = false
}

const handleDrop = (e: DragEvent) => {
  e.preventDefault()
  isDragOver.value = false

  const files = Array.from(e.dataTransfer?.files || [])
  files.forEach(handleBeforeUpload)
}

// 移除文件
const handleRemoveFile = (file: any) => {
  const pathToRemove = file.path || file.url

  let newValue: string | string[]
  if (props.multiple) {
    const currentPaths = Array.isArray(props.modelValue) ? props.modelValue : (props.modelValue ? [props.modelValue] : [])
    newValue = currentPaths.filter(path => path !== pathToRemove)
  } else {
    newValue = ''
  }

  emit('update:modelValue', newValue)
  emit('change', newValue)
  message.success('文件已移除')
}

// 上传前的处理
const handleBeforeUpload = async (file: File) => {
  // 文件验证
  if (!validateFileSize(file) || !validateFileType(file)) {
    return false
  }

    try {
    uploading.value = true

    // 模拟上传（可以替换为真实的上传逻辑）
    const uploadPath = await simulateUpload(file)

    // 更新文件路径
    let newValue: string | string[]
    if (props.multiple) {
      const currentPaths = Array.isArray(props.modelValue) ? props.modelValue : (props.modelValue ? [props.modelValue] : [])
      newValue = [...currentPaths, uploadPath]
    } else {
      newValue = uploadPath
    }

    emit('update:modelValue', newValue)
    emit('change', newValue)
    emit('success', { filePath: uploadPath }, file)

    message.success(`文件 ${file.name} 上传成功`)
  } catch (error) {
    console.error('文件上传失败:', error)
    emit('error', error, file)
    message.error(`文件 ${file.name} 上传失败`)
  } finally {
    uploading.value = false
  }

  return false // 阻止默认上传行为
}

// 模拟上传函数（可以替换为真实的上传实现）
const simulateUpload = async (file: File): Promise<string> => {
  // 模拟网络延迟
  await new Promise(resolve => setTimeout(resolve, 1000))

  // 生成模拟的文件路径
  const timestamp = Date.now()
  const extension = file.name.split('.').pop()
  return `/uploads/${timestamp}_${file.name}`
}

// 真实上传函数（示例）
const realUpload = async (file: File): Promise<string> => {
  const formData = new FormData()
  formData.append('file', file)

  const response = await fetch(props.uploadUrl, {
    method: 'POST',
    body: formData
  })

  if (!response.ok) {
    throw new Error(`上传失败: ${response.statusText}`)
  }

  const result = await response.json()
  return result.filePath || result.url || result.path
}

// 旧的移除函数已被handleRemoveFile替代
</script>

<style scoped>
.file-upload-wrapper {
  width: 100%;
}

/* 上传区域样式 */
.upload-area {
  border: 2px dashed #d9d9d9;
  border-radius: 12px;
  background: #fafafa;
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.upload-area:hover {
  border-color: #1890ff;
  background: #f0f8ff;
}

.upload-area--dragover {
  border-color: #1890ff;
  background: #e6f7ff;
  transform: scale(1.02);
  box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15);
}

.upload-area--disabled {
  opacity: 0.6;
  cursor: not-allowed;
  border-color: #d9d9d9;
  background: #f5f5f5;
}

.upload-area--has-files {
  border-style: solid;
  border-color: #d9d9d9;
  background: #fafafa;
}

.upload-trigger {
  width: 100%;
}

.upload-trigger :deep(.ant-upload) {
  width: 100%;
  display: block;
}

.upload-content {
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  user-select: none;
}

.upload-icon {
  font-size: 48px;
  color: #8c8c8c;
  margin-bottom: 16px;
  transition: all 0.3s ease;
}

.upload-area:hover .upload-icon {
  color: #1890ff;
  transform: translateY(-2px);
}

.upload-loading {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.upload-text {
  color: #666;
}

.upload-title {
  font-size: 16px;
  font-weight: 500;
  color: #262626;
  margin-bottom: 8px;
  transition: color 0.3s ease;
}

.upload-area:hover .upload-title {
  color: #1890ff;
}

.upload-hint {
  font-size: 14px;
  color: #8c8c8c;
  margin-bottom: 4px;
}

.upload-types {
  font-size: 12px;
  color: #bfbfbf;
  margin-top: 8px;
}

/* 文件列表样式 */
.file-list {
  margin-top: 16px;
  border: 1px solid #f0f0f0;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
}

.file-list-header {
  padding: 12px 16px;
  background: #fafafa;
  border-bottom: 1px solid #f0f0f0;
}

.file-count {
  font-size: 14px;
  color: #595959;
  font-weight: 500;
}

.file-items {
  max-height: 200px;
  overflow-y: auto;
}

.file-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid #f5f5f5;
  transition: background-color 0.2s ease;
}

.file-item:last-child {
  border-bottom: none;
}

.file-item:hover {
  background: #f9f9f9;
}

.file-info {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.file-icon {
  font-size: 20px;
  color: #1890ff;
  margin-right: 12px;
  flex-shrink: 0;
}

.file-details {
  flex: 1;
  min-width: 0;
}

.file-name {
  font-size: 14px;
  color: #262626;
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-status {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: #52c41a;
}

.status-success {
  margin-right: 4px;
  font-size: 14px;
}

.file-actions {
  flex-shrink: 0;
  margin-left: 12px;
}

.remove-btn {
  opacity: 0.6;
  transition: all 0.2s ease;
}

.remove-btn:hover {
  opacity: 1;
  color: #ff4d4f !important;
  transform: scale(1.1);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .upload-content {
    padding: 30px 16px;
  }

  .upload-icon {
    font-size: 36px;
    margin-bottom: 12px;
  }

  .upload-title {
    font-size: 15px;
  }

  .upload-hint {
    font-size: 13px;
  }

  .file-item {
    padding: 10px 12px;
  }

  .file-name {
    font-size: 13px;
  }
}

/* 无障碍支持 */
.upload-area:focus-within {
  outline: 2px solid #1890ff;
  outline-offset: 2px;
}

/* 动画效果 */
.file-item {
  animation: slideIn 0.3s ease;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 拖拽指示器 */
.upload-area--dragover::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(45deg, rgba(24, 144, 255, 0.1) 25%, transparent 25%, transparent 75%, rgba(24, 144, 255, 0.1) 75%),
              linear-gradient(45deg, rgba(24, 144, 255, 0.1) 25%, transparent 25%, transparent 75%, rgba(24, 144, 255, 0.1) 75%);
  background-size: 20px 20px;
  background-position: 0 0, 10px 10px;
  animation: move 0.5s linear infinite;
  z-index: -1;
}

@keyframes move {
  0% { background-position: 0 0, 10px 10px; }
  100% { background-position: 20px 20px, 30px 30px; }
}
</style>